/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * ClientUI.java
 *
 * Created on 07.11.2011, 1:21:54
 */
package client.ui;

import client.ui.fileTransmiting.FileTransmiting;
import protocolHandler.ProtoMessageCreator;
import protocolHandler.ProtoMessageParser;
import client.net.ConnectParams;
import client.pipeConnector.IPipe;
import client.ui.chatJPanelActivating.ChatJpanelActivatedEvent;
import client.ui.chatJPanelActivating.ChatJpanelActivatedListener;
import client.ui.chatJPanelActivating.ChatJpanelActivatedProducer;
import client.ui.fileTransmiting.TransmitedFileIsAlreadyInListException;
import java.io.File;
import java.io.IOException;
import protocolHandler.HeaderCodes;
import java.util.HashMap;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
 *
 * @author Александр Емельянов (mr.lex91@gmail.com)
 */
public class ClientUI extends javax.swing.JFrame{

    /** Creates new form ClientUI */
    public ClientUI(IPipe pipeConnector) {
        this.pipeConnector=pipeConnector;
        initComponents();
        chatJPanel1.Disable();
        jMenuItem3.setEnabled(false);
        encoding=System.getProperty("file.encoding");
        isUTF8Encoding=encoding.equalsIgnoreCase("UTF8");
        //chatJPanel1.setEncodingProperties(encoding, isUTF8Encoding);
        listChatHeaders.put("Чат","Чат");
        listChat.put("Чат", chatJPanel1);
        actProd.setListener(new ChatJpanelActivatedListener() {

            @Override
            public void chatPanelActivated(ChatJpanelActivatedEvent ev) {
                String nick=ev.getNickName();
                if (nick==null) return;
                if (nick.equals(nickName)) nick="Чат";
                String tabHeader=listChatHeaders.get(nick);
                activateTab(tabHeader, jTabbedPane1.indexOfTab(tabHeader));
            }
        });
	jMenuItem7.setEnabled(false);
	jMenuItem8.setEnabled(false);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPopupMenu1 = new javax.swing.JPopupMenu();
        jMenuItem8 = new javax.swing.JMenuItem();
        jMenuItem7 = new javax.swing.JMenuItem();
        jFileChooser1 = new javax.swing.JFileChooser();
        jScrollPane3 = new javax.swing.JScrollPane();
        jList1 = new javax.swing.JList();
        jLabel3 = new javax.swing.JLabel();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        chatJPanel1 = new client.ui.ChatJPanel(pipeConnector, "Send", nickName, actProd);
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenuItem4 = new javax.swing.JMenuItem();
        jMenuItem5 = new javax.swing.JMenuItem();
        jMenuItem2 = new javax.swing.JMenuItem();
        jMenuItem3 = new javax.swing.JMenuItem();
        jMenuItem6 = new javax.swing.JMenuItem();

        jMenuItem8.setText("Личное сообщение");
        jMenuItem8.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem8ActionPerformed(evt);
            }
        });
        jPopupMenu1.add(jMenuItem8);

        jMenuItem7.setText("Отправить файл");
        jMenuItem7.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem7ActionPerformed(evt);
            }
        });
        jPopupMenu1.add(jMenuItem7);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Чат[]");
        setMinimumSize(new java.awt.Dimension(408, 254));

        jList1.setComponentPopupMenu(jPopupMenu1);
        jList1.setMaximumSize(new java.awt.Dimension(33, 40));
        jList1.setMinimumSize(new java.awt.Dimension(33, 180));
        jList1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jList1MouseClicked(evt);
            }
        });
        jScrollPane3.setViewportView(jList1);

        jLabel3.setText("Список участников:");

        jTabbedPane1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTabbedPane1MouseClicked(evt);
            }
        });
        jTabbedPane1.addTab("Чат", chatJPanel1);

        jMenu1.setText("Меню");

        jMenuItem1.setText("Войти");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem1);

        jMenuItem4.setText("Создать аккаунт");
        jMenuItem4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem4ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem4);

        jMenuItem5.setText("Удалить аккаунт");
        jMenuItem5.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem5ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem5);

        jMenuItem2.setText("Настройки");
        jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem2ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem2);

        jMenuItem3.setText("Выйти");
        jMenuItem3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem3ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem3);

        jMenuItem6.setText("Закрыть");
        jMenuItem6.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem6ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem6);

        jMenuBar1.add(jMenu1);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 563, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 485, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 460, Short.MAX_VALUE)))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem1ActionPerformed
        // TODO add your handling code here:
        AuthInfoDialog dialogWind=new AuthInfoDialog((JFrame)this, "Вход");
        int choise=dialogWind.Show();
        if (choise==1)
        {
            String[] param=dialogWind.getAuthInf();
            ProtoMessageCreator creator=new ProtoMessageCreator();
            creator.setType("LogIn");
            creator.addHeader("NickName", param[0]);
            creator.addHeader("Password", param[1]);
            pipeConnector.Write(creator.Create());
            nickName=param[0];
        }
    }//GEN-LAST:event_jMenuItem1ActionPerformed

    private void jMenuItem6ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem6ActionPerformed
        // TODO add your handling code here:
        System.exit(0);
    }//GEN-LAST:event_jMenuItem6ActionPerformed

    private void jMenuItem4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem4ActionPerformed
        // TODO add your handling code here:
        AuthInfoDialog dialogWind=new AuthInfoDialog((JFrame)this, "Создать аккаунт");
        int choise=dialogWind.Show();
        if (choise==1)
        {
            String[] param=dialogWind.getAuthInf();
            ProtoMessageCreator creator=new ProtoMessageCreator();
            creator.setType("CreateAcc");
            creator.addHeader("NickName", param[0]);
            creator.addHeader("Password", param[1]);
            pipeConnector.Write(creator.Create());
        }
    }//GEN-LAST:event_jMenuItem4ActionPerformed

    private void jMenuItem5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem5ActionPerformed
        // TODO add your handling code here:
        AuthInfoDialog dialogWind=new AuthInfoDialog((JFrame)this, "Удалить аккаунт");
        int choise=dialogWind.Show();
        if (choise==1)
        {
            String[] param=dialogWind.getAuthInf();
            ProtoMessageCreator creator=new ProtoMessageCreator();
            creator.setType("DeleteAcc");
            creator.addHeader("NickName", param[0]);
            creator.addHeader("Password", param[1]);
            pipeConnector.Write(creator.Create());
        }
    }//GEN-LAST:event_jMenuItem5ActionPerformed

    private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed
        // TODO add your handling code here:
        ConnectParameters dialogWind=new ConnectParameters((JFrame)this, param);
        int choise=dialogWind.Show();
        if (choise==1)
        {
            param=dialogWind.GetParameters();
            ProtoMessageCreator creator=new ProtoMessageCreator();
            creator.setType("ConnectParams");
            creator.addHeader("Host", param.getHost());
            creator.addHeader("Port", String.valueOf(param.getPort()));
            pipeConnector.Write(creator.Create());
        }
    }//GEN-LAST:event_jMenuItem2ActionPerformed

    private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem3ActionPerformed
        // TODO add your handling code here:
        ProtoMessageCreator creator=new ProtoMessageCreator();
        creator.setType("LogOut");
        pipeConnector.Write(creator.Create());
        jMenuItem1.setEnabled(true);
        jMenuItem2.setEnabled(true);
        chatJPanel1.Disable();
        jMenuItem3.setEnabled(false);
        for(String header:listChatHeaders.values())
        {
            listChat.get(header).Disable();
        }
        this.setTitle("Чат[]");
        String[] str={""};
        jList1.setListData(str);
    }//GEN-LAST:event_jMenuItem3ActionPerformed

    private void jList1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jList1MouseClicked
        // TODO add your handling code here:
        if (evt.getButton()==1) if(evt.getClickCount()==2) chatJPanel1.ConverseTo((String) jList1.getSelectedValue());
	if (jList1.isSelectionEmpty()) 
	{
	    jMenuItem7.setEnabled(false);
	    jMenuItem8.setEnabled(false);
	}
	else
	{
	    jMenuItem7.setEnabled(true);
	    jMenuItem8.setEnabled(true);
	}
    }//GEN-LAST:event_jList1MouseClicked

    private void jTabbedPane1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTabbedPane1MouseClicked
        // TODO add your handling code here:
        if (evt.getButton()==1)
        {
            int ind=jTabbedPane1.getSelectedIndex();
            String str=jTabbedPane1.getTitleAt(ind);
            activateTab(str, ind);
        }
        else
        {
            int index=jTabbedPane1.getSelectedIndex();
            String name=jTabbedPane1.getTitleAt(index);
            listChat.remove(listChatHeaders.get(name));
            listChatHeaders.remove(name);
            if (index!=0) jTabbedPane1.remove(index);
        }

    }//GEN-LAST:event_jTabbedPane1MouseClicked

    private void jMenuItem8ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem8ActionPerformed
        // TODO add your handling code here:
            String nick=(String)jList1.getSelectedValue();
            if (nick!=null  && !listChatHeaders.containsKey(nick)) addSendTo(nick);
    }//GEN-LAST:event_jMenuItem8ActionPerformed

    private void jMenuItem7ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem7ActionPerformed
        // TODO add your handtling code here:
        String nick=(String)jList1.getSelectedValue();
        if (nick!=null)
            if (jFileChooser1.showOpenDialog(this)==javax.swing.JFileChooser.OPEN_DIALOG)
            {
                File f=jFileChooser1.getSelectedFile();
                try {
                    FileTransmiting.FileTransmitingParams transmitingParams=ftWindow.transmit(nick, f);
                    ProtoMessageCreator creator=new ProtoMessageCreator();
                    creator.setType("SendFile");
                    creator.addHeader("Address", nick);
                    creator.addHeader("Host", transmitingParams.host);
                    creator.addHeader("Port", transmitingParams.port);
                    creator.addHeader("FileName", transmitingParams.fileName);
                    creator.addHeader("FileRequest", transmitingParams.fileRequest);
                    creator.addHeader("FileSize", transmitingParams.fileSize);
                    pipeConnector.Write(creator.Create());
                } catch (TransmitedFileIsAlreadyInListException ex) {
		    new MsgDialog(this, "Передача файла", "Вы уже передаете "+f.getName()+" пользователю "+nick).Show();
		}catch (IOException ex) {
		    JOptionPane.showConfirmDialog(null,"Не удалось установить соединение для передачи файла "+f.getName()+" пользователю "+nick+"\nПопробуйте снова","Передача файла",JOptionPane.ERROR_MESSAGE);
		    //new MsgDialog(this, "Передача файла", "Не удалось установить соединение для передачи файла "+f.getName()+" пользователю "+nick+"\nПопробуйте снова").Show();
		    pipeConnector.Write("InetInfo");
		}
            }
    }//GEN-LAST:event_jMenuItem7ActionPerformed
    private ChatJPanel addSendTo(String nick)
    {
        ChatJPanel chat=new ChatJPanel(pipeConnector, "SendTo", nickName, actProd);
        chat.Enable(nick);
        //chat.setEncodingProperties(encoding, isUTF8Encoding);
        listChat.put(nick, chat);
        listChatHeaders.put(nick, "*"+nick);
        jTabbedPane1.add("*"+nick,chat);
        return chat;
    }
    public void Show() {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                setVisible(true);
            }
        });
        new Thread(new Runnable()
        {
            public void run()
            {
                perfomInputPipe();
            }
        }).start();
    }
    private void activateTab(String str, int index)
    {
        if (str.indexOf("*")==0)
        {
            str=str.substring(1,str.length());
            listChatHeaders.remove(str);
            listChatHeaders.put(str, str);
            jTabbedPane1.setTitleAt(index, str);
        }
    }
    private void perfomInputPipe()
    {
        ProtoMessageParser parser=new ProtoMessageParser();
        while (true)
        {
            String str=pipeConnector.Read();
            parser.Parse(str);
            switch(HeaderCodes.getResponseHeaderCode(parser.getType()))
            {
                case 1:
                {
		    
                    (new MsgDialog(this,"Создать аккаунт", "Аккаунт уже существует")).Show();
                    break;
                }
                case 2:
                {
                    (new MsgDialog(this,"Чат", "Аккаунт не существует")).Show();
                    break;
                }
                case 3:
                {
                    nickName="";
                    (new MsgDialog(this,"Чат", "Ошибка авторизации")).Show();
                    break;
                }
                case 4:
                {
                    endOnLine("Сервер закрыл соединение");
                    break;
                }
                case 5:
                {
                    String msg=parser.getHeaderVal("Text");
                    chatJPanel1.Message(parser.getHeaderVal("Address")+": "+msg);
                    jTabbedPane1.setTitleAt(0, "*Чат");
                    listChatHeaders.remove("Чат");
                    listChatHeaders.put("Чат", "*Чат");
                    break;
                }
                case 6:
                {
                    String msg=parser.getHeaderVal("Text");
                    String nick=parser.getHeaderVal("Address");
                    if (listChat.containsKey(nick))
                    {
                        listChat.get(nick).Message(nick+": "+msg);
                        if (!listChatHeaders.containsValue("*"+nick))
			{
			    listChatHeaders.remove(nick);
			    listChatHeaders.put(nick, "*"+nick);
			    jTabbedPane1.setTitleAt(jTabbedPane1.indexOfTab(nick), "*"+nick);
			}
                    }
                    else addSendTo(nick).Message(nick+": "+msg);
                    break;
                }
                case 7:break;
                case 8:
                {
                    roster=new Roster(parser.getHeaderVal("Folowers"), Integer.valueOf(parser.getHeaderVal("Size")), nickName);
                    jList1.setListData(roster.getRoster());
                    break;
                }
                case 9:
                {
                    (new MsgDialog(this,"Чат", "Неверные настройки сервера")).Show();
                    jMenuItem2ActionPerformed(null);
                    break;
                }
                case 10:
                {
                    (new MsgDialog(this,"Создать аккаунт", "Аккаунт создан")).Show();
                    break;
                }
                case 11:
                {
                    (new MsgDialog(this,"Удалить аккаунт", "Аккаунт удален")).Show();
                    break;
                }
                case 12:
                {
                    chatJPanel1.Enable(nickName);
                    chatJPanel1.setMyNickName(nickName);
                    jMenuItem2.setEnabled(false);
                    jMenuItem1.setEnabled(false);
                    jMenuItem3.setEnabled(true);
                    this.setTitle("Чат["+nickName+"]");
                    break;
                }
                case 13:
                {
                    param.setHost(parser.getHeaderVal("Host"));
                    param.setPort(Integer.valueOf(parser.getHeaderVal("Port")));
                    break;
                }
                case 14:
                {
                    endOnLine("Соединение оборвалось");
                    break;
                }
                case 15:
                {
                    chatJPanel1.Message("Пользователь онлайн: "+parser.getHeaderVal("Address"));
                    roster.addToList(parser.getHeaderVal("Address"));
                    jList1.setListData(roster.getRoster());
                    break;
                }
                case 16:
                {
                    chatJPanel1.Message("Пользователь оффлайн: "+parser.getHeaderVal("Address"));
                    roster.deleteFromList(parser.getHeaderVal("Address"));
                    jList1.setListData(roster.getRoster());
                    break;
                }
                case 17:
                {
                    (new MsgDialog(this,"Чат", "Пользователь уже авторизован")).Show();
                    break;
                }
                case 18:
                {
                    int result=JOptionPane.showConfirmDialog(null,"Принять файл \""+parser.getHeaderVal("FileName")
                            +"\" от пользователя "+parser.getHeaderVal("Address")+"?","Передача файла",JOptionPane.YES_NO_OPTION);
                    if (result==0)
                    {
			if (jFileChooser1.showSaveDialog(this)==0)
			{
			    File f=jFileChooser1.getSelectedFile();
			    try {
				ftWindow.receive(parser.getHeaderVal("Address"), parser.getHeaderVal("Host"), parser.getHeaderVal("Port"), f, parser.getHeaderVal("FileRequest"), Long.valueOf(parser.getHeaderVal("FileSize")));
			    } catch (TransmitedFileIsAlreadyInListException ex) {
				//Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
			    } catch (IOException ex) {
				JOptionPane.showConfirmDialog(null,"Не удалось установить соединение для принятия файла "+parser.getHeaderVal("FileName")+" от пользователя "+parser.getHeaderVal("Address")+"\nПопробуйте снова","Передача файла",JOptionPane.ERROR_MESSAGE);
				//new MsgDialog(this, "Передача файла", "Не удалось установить соединение для принятия файла "+parser.getHeaderVal("FileName")+" от пользователя "+parser.getHeaderVal("Address")+"\nПопробуйте снова").Show();
			    }
			}
                        else
                        {
                            //send cancel message
                        }
		    }
		    break;
		}
		case 19:
		{
		    ftWindow.setHost(parser.getHeaderVal("Host"));
		}
            }
            parser.clear();
        }
    }
    private void endOnLine(String msg)
    {
        chatJPanel1.Disable();
        jMenuItem2.setEnabled(true);
        jMenuItem1.setEnabled(true);
        jMenuItem3.setEnabled(false);
        if (!listChatHeaders.isEmpty())
            for(String header:listChatHeaders.values())
            {
                listChat.get(header).Disable();
            }
        (new MsgDialog(this,"Чат", msg)).Show();
        this.setTitle("Чат[]");
        String[] str={""};
        jList1.setListData(str);
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private client.ui.ChatJPanel chatJPanel1;
    private javax.swing.JFileChooser jFileChooser1;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JList jList1;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JMenuItem jMenuItem3;
    private javax.swing.JMenuItem jMenuItem4;
    private javax.swing.JMenuItem jMenuItem5;
    private javax.swing.JMenuItem jMenuItem6;
    private javax.swing.JMenuItem jMenuItem7;
    private javax.swing.JMenuItem jMenuItem8;
    private javax.swing.JPopupMenu jPopupMenu1;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JTabbedPane jTabbedPane1;
    // End of variables declaration//GEN-END:variables
    private IPipe pipeConnector;
    private ConnectParams param=new ConnectParams();
    private String nickName="";
    private Roster roster;
    private HashMap<String, ChatJPanel> listChat=new HashMap<String, ChatJPanel>();
    private HashMap<String, String> listChatHeaders= new HashMap<String, String>();
    private boolean isUTF8Encoding;
    private String encoding;
    private FileTransmiting ftWindow=new FileTransmiting(this);
    private ChatJpanelActivatedProducer actProd=new ChatJpanelActivatedProducer();
}
